package com.apobates.forum.letterbox.service;

import com.apobates.forum.letterbox.entity.ForumLetter;
import com.apobates.forum.letterbox.entity.ForumLetterTypeEnum;
import com.apobates.forum.letterbox.entity.proxy.ForumLetterReplica;
import com.apobates.forum.utils.persistence.Page;
import com.apobates.forum.utils.persistence.Pageable;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;

/**
 *
 * @author xiaofanku
 * @since 20200510
 */
public interface InboxService {
    /**
     * 查看指定会员的收件箱,级联加载信件在收件箱中的状态(ForumLetterStatus)
     *
     * @param memberId 会员ID/信件的收件人
     * @param pageable 分页请求参数
     * @return
     */
    Page<ForumLetterReplica> getInBox(long memberId, Pageable pageable);
    /**
     * 查看指定会员的收件箱,级联加载信件在收件箱中的状态(ForumLetterStatus)
     * 
     * @param memberId 会员ID/信件的收件人
     * @param pageable 分页请求参数
     * @return 
     */
    Page<ForumLetter> getInBoxGroupSender(long memberId, Pageable pageable);
    
    /**
     * 查看指定会员的收件箱,级联加载信件在收件箱中的状态(ForumLetterStatus)
     *
     * @param memberId 会员ID/信件的收件人
     * @param label 信件类型
     * @param pageable 分页请求参数
     * @return
     */
    Page<ForumLetterReplica> getInBox(long memberId, ForumLetterTypeEnum label, Pageable pageable);
    
    /**
     * 查看未读的信件(不包含删除的)
     *
     * @param memberId 会员ID/信件的收件人
     * @param size 显示的数量
     * @return
     */
    Stream<ForumLetter> getReadableMessages(long memberId, int size);
    
    /**
     * 查看发件人发来的所有信件 只包含发件人发来的信件.会员回复的信件不包含在内
     *
     * @param sender 信件的发件人
     * @param memberId 会员ID/信件的收件人
     * @return
     */
    Stream<ForumLetter> get(long sender, long memberId);
    
    /**
     * 查看发件人发来的所有信件,自参考日期往后的信件 只包含发件人发来的信件.会员回复的信件不包含在内
     *
     * @param sender 信件的发件人
     * @param memberId 会员ID/信件的收件人
     * @param prevUnixStamp 参考日期
     * @return
     */
    Stream<ForumLetter> get(long sender, long memberId, int prevUnixStamp);
    
    /**
     * 将发件人发送的信件全部标记为阅读
     *
     * @param memberId 会员ID/信件的收件人
     * @param sender 信件的发件人
     * @return
     */
    Optional<Boolean> readed(long memberId, long sender);
    
    /**
     * 阅读指定的信件
     *
     * @param memberId 会员ID/信件的收件人
     * @param idList 信件记录ID列表ForumLetter.id(!= Inbox.id)
     * @return
     */
    int readed(long memberId, List<Long> idList);
    
    /**
     * 将收件人的未读信件标记为阅读
     *
     * @param memberId 会员ID/信件的收件人
     * @return
     */
    int readed(long memberId);

    /**
     * 复合标记为已读,复合(int readed(long) || Optional<Boolean> readed(long, long))
     *
     * @param memberId 主向会员
     * @param othMemberId
     * @param direction 方向
     * @return
     */
    Optional<Boolean> compositeReaded(long memberId, long othMemberId, int direction);

    /**
     * 删除指定的信件
     *
     * @param memberId 会员ID/信件的收件人
     * @param idList 信件记录ID列表ForumLetter.id(!= Inbox.id)
     * @return
     */
    int remove(long memberId, List<Long> idList);
    
    /**
     * 查看未读的信件数量(不包含删除的)
     *
     * @param memberId 会员ID/信件的收件人
     * @return
     */
    long countForMemberMessages(long memberId);
    
    /**
     * 分组统计指定发件人未读的信件数量
     *
     * @param memberId 会员ID/信件的收件人
     * @param senderIdSet 信件的发件人ID集合
     * @return Key=信件的发件人ID, Value=收件人未读的信件数量
     */
    Map<Long, Long> groupForMemberMessages(long memberId, Set<Long> senderIdSet);
}